// psychadelicsquare.cpp
// Authors: Andrew Forney and David Hara
// --------------------------------------------------
// Exercise in view manipulation and translation by
// making a psychadelic square and viewing it from an
// alternate angle.

#ifdef __APPLE_CC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <cstdlib>
#include <ctime>

// Initialize constants and declare the static
// color array that will be referenced for the vertex
// coloring.
static const int LENGTH = 10;
static const int WIDTH = 10;
static float colorMatrix[LENGTH + 1][WIDTH + 1][3];

// HELPER FUNCTION: Called in init() to populate
// the color matrix for use on the vertices
void colorMatrixFill(int length, int width){

    // Set up the rand() function to be a little more
    // random than the crappy default.
    srand(time(NULL));

    for (int i = 0; i < length + 1; i++) {
        for (int j = 0; j < width + 1; j++) {
            for (int k = 0; k < 3; k++) {
                colorMatrix[i][j][k] = (float) rand()/RAND_MAX;
            }
        }
    }

}

// Draws the psychadelic square
void display() {

    // Clear the color buffer
    glClear(GL_COLOR_BUFFER_BIT);

    // Initiate the drawing sequence, adding the vertices
    // a row at a time
    for (int i = 0; i < WIDTH; i++) {
        glBegin(GL_QUAD_STRIP);
            for (int j = 0; j <= LENGTH; j++) {
                glColor3fv(colorMatrix[j][i]);
                glVertex3f(j, 0, i);
                glColor3fv(colorMatrix[j][i+1]);
                glVertex3f(j, 0, i + 1);
            }
        glEnd();
    }

    glFlush();

}

// Sets up global attributes like clear color and the color matrix,
// and then adjusts the camera for an "interesting perspective."
void init() {

    // Set the camera lens to a 4:3 aspect ratio with near clipping
    // plane 1 and far 40; angle of 60 degrees
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, 4.0/3.0, 1, 40);

    // Position the camera at (3, 8, 10)
    // looking at (0, 0, 0) with y as the up vector.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(3, 8, 10, 0, 0, 0, 0, 1, 0);

    // Translate the square onto the origin
    glTranslatef(-(LENGTH/2), 0, -(WIDTH/2));

}

// Initializes GLUT, the display mode, and main window; registers callbacks;
// does application initialization; enters the main event loop.
int main(int argc, char** argv) {

    // Fill the color matrix using the above helper method
    colorMatrixFill(LENGTH, WIDTH);

    // Set up the other methods and glut stuff
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(80, 80);
    glutInitWindowSize(800, 600);
    glutCreateWindow("A Psychadelic Square Pattern");
    glutDisplayFunc(display);
    init();
    glutMainLoop();

}
